    ;^Z80^
    TITLE FILE: TAPE_MANA:TOS      HEWLETT-PACKARD: TAPE_MANAGER  (c) Coleco 1983 Confidential
    ;NAME ^Rev 6 - DTT^

    DESCR_               MACRO
                           .GOTO ENDESCR_1

     Author:       DTT
     Project:      ________, ___
     Starting date:18feb83

     Prom release Date:
     Prom release Rev:

     Header Rev: 3

     ********************************
     *                              *
     *  TAPE_MANAGER    DTT         *
     *                              *
     ********************************

           Rev History (one line note indicating the change)

           Rev.  Date         Name      Change
            6    11/16/83  DTT       ADDED DEVICE ID TO SIMULATE DEVICE INDEPENDENCE
            5    12spt83   DTT       MODIFIED ERROR SYSTEM TO WRITE ERRORS TO CSA AREA
            4    08aug83   DTT       SIMULATES WRITES!
            3    07jul83   DTT       ADDED KILL_TAPE/CSA
            2    30jun83   DTT       STATE MACHINE FOR MULTI TASKING
            1    05apr83   DTT       BINK ON I/O ERROR, REMOVING TIMING STUFF, EI AND DI ADDED.
            0    10feb83   DTT       Initial Pseudo Code

     NAME: TAPE_MANAGER  (OVERLAY CONTROL)

     FUNCTION: (LOAD OVERLAYS VIA SIMULATED I/O WITH THE HP64000)

     INPUTS:   (ACCUMULATOR = OVERLAY NUMBER)

     OUTPUTS:  (OVERLAY IS LOADED TO RAM ADDRESS)

     PSEUDOCODE:  (PASCAL type pseudocode of procedure.)

             ----------------     overlay request? Y       ----------------
            :                :----------------------->    :                :
      :---->:    IDLE        :                            :    RENAME      :
      :     :                :                            :                :
      :     :                :---------:                  :                :
      :      ----------------          :                   ----------------
      :                /:\   overlay request? N                    :
      :                 :______________:                           :
      :                                                            :
      :                                                            :
      :                                                            :
      :                                                            :
      :                                                            :
      :                                                            :
      :                                                           \:/
      :      ----------------                              ----------------
      :     :                :                            :                :
      :     :    READ        : <--------------------------:      OPEN      :
      :     :    FIRST       :                            :                :
      :     :    RECORD      :                            :                :
      :      ------:---------                              ----------------
      :            :
      :            :
      :           \:/
      :      ----------------                              ----------------
      :     :                :------------------------>   :                :
      :     :    READ        :                            :    MOVE DATA   :
      :     :    DATA        :    end of file? N          :   FROM BUFFER  :
      :     :    RECORD      : <--------------------------:      TO RAM    :
      :      ----------------                              --------:-------
      :                                                            :
      :                                                      end of file? Y
      :                                                           \:/
      :      ----------------                              ----------------
      :     :                :                            :                :
       -----: PRE IDLE STATE :<---------------------------:      CLOSE     :
            :(WAIT FOR CLOSE):                            :                :
            :                :                            :                :
             ----------------                              ----------------
    ENDESCR_1       MEND

    DESC_a              MACRO
     .GOTO              DESC_a
     ***********************************************************************************************
      Each transition state looks like this:

       from previous
    =================:
          state      :
                    \:/
              ----------------:                      -----------------
             :                :  I/O errors? Y      :                 :
             : TRANSITION     :-------------------> :  ERROR STATE    :
        :===>:                :                     :  (terminate)    :----:
        :    :                :=====:               :                 :    :
        :     ----------------      :                ----------:------     :
        :            :              :                         /:\          :
        :            :              :                          :           :
        :  sim i/o   :             \:/                         :___________:
         ------------         ---------------- to state 6
           function          :                :============>
           complete? N       : TEST FOR       :
                             : ABORT          :to state 7
                             : REQUEST        :============>
                              ----------------
                               no   :
                             abort  : to next
                                    : state
                                   \:/

    DESC_a          MEND

    DESC_2          MACRO
     .GOTO          DESC_2
    *
    ***************************************************************************************
    *

        COMMON ATTRIBUTE AREAS (COMMUNICATION BUFFER WITH HP)
        ALL VALUES ARE HEXADECIMAL

        1) ASSIGN FILENAME TO CA
            CA      CA+1     CA+2             CA+n
         -------- -------- -------- -------- -------- -------- -------- --------
        :   8A   :LENGTH  :FILENAME ------> : USER ID         :  NOT
        :        :BYTE    :UP TO 9 BYTES    : UP TO 5 BYTES   :  USED----->
         -------- -------- -------- -------- -------- -------- -------- --------
         LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8)
         FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
         USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.

        2) OPEN
            CA      CA+1     CA+2
         -------- -------- -------- -------- -------- -------- -------- --------
        :   81   :   04   :   00   : NOT
        :        :        :        : USED------------------------------->
         -------- -------- -------- -------- -------- -------- -------- --------
         CA+1 MUST BE 04HEX DESIGNATES ABSOLUTE FILE WILL BE OPENED.
         CA+2 MUST BE 00HEX DESIGNATES DISK NUMBER.

        3) CLOSE
            CA
         -------- -------- -------- -------- -------- -------- -------- --------
        :   82   :  NOT
        :        :  USED ----------------------------------------------->
         -------- -------- -------- -------- -------- -------- -------- --------

        4) READ
            CA      CA+1     CA+2              CA+4              CA+6
         -------- -------- -------- -------- -------- -------- -------- --------
        :   87   :   80   : #BYTES TO LOAD  :  N/A   :  N/A   : LOAD ADDRESS
        :        :        :  MSB   :  LSB   :        :        :  MSB   :  LSB
         -------- -------- -------- -------- -------- -------- -------- --------
         CA+1 DEFINES THE BUFFER LENGTH IN WORDS - 1 MUST BE LOADED BEFORE CALLING SIM I/O
         CA+2 DEFINES NUMBER OF BYTES TO MOVE TO RAM FROM THE SIM I/O BUFFER
         CA+6 DEFINES THE RAM ADDRESS TO LOAD TO
         CA+8 (NOT SHOWN) IS THE START OF THE SIM I/O BUFFER
         NOTE: CA+2 AND CA+6 ARE ONE WORD LONG BUT NOT STORED AS Z80 WORDS.
               THE Z80 EXPECTS WORD VALUES TO BE STORED LSB/MSB.

    DESC_2
           MEND

    NEXT_STATE      MACRO LP1
             LD     A,LP1                          ;SOMETHING IN THE COMMAND BUFFER!
             LD     [TAPE_STATE],A
             LD     HL,[STATE_VECTORS+LP1+LP1]
             LD     [NEXT_STATE_ADDRESS],HL
             JP     END_OF_STATE_MACHINE
                    MEND
    ;SUBROUTINES CALLED:
    ;      EXT

    ;OPERATING SYSTEM CALLS:

    ;EXTERNAL DATA AREAS USED:
                    EXT KILL_TAPE
                    EXT WRITE_TAPE
                    EXT CSA
                    EXT TAPE_STATE
                    EXT OVERLAY_NUMBER

    ;GLOBAL DATA AREAS DEFINED:
             GLOBAL DEVICE_ID

    ;LOCAL EQUATES
    CA       EQU    07400H                         ;COMMON ATTRIBUTES AREA FOR SIM I/O
    BUF_LEN  EQU    CA+1
    FILETYPE EQU    CA+1                           ;FILETYPE ADDRESS IN C_A_
    DISC_NUM EQU    FILETYPE+1                     ;DISK NUMBER ADDRESS IN C_A_
    REC_LEN  EQU    CA+2                           ;RECORD LENGTH ADDRESS IN C_A_
    BUFFER   EQU    CA+8                           ;I_O_BUFFER
    RNAM_BUF EQU    CA+1                           ;RENAME BUFFER AREA
    LOADADDR EQU    CA+4                           ;ADDRESS OF MEM ADDRESS OF OVERLAY

    MAXBUFLN EQU    128                            ;UP TO 128 WORDS MAY BE READ IN
    ABSOLUTE EQU    004H                           ;FILE TYPE IS ABSOLUTE
    OPEN     EQU    081H
    CLOSE    EQU    082H
    READ     EQU    087H
    WRITE    EQU    089H
    RENAME   EQU    08AH

    ;GLOBAL EQUATES
    ;      INCLUDE equate file name

           PROG
           GLOBAL   TAPE_MANAGER

           GLOBAL   INITIALIZE_TAPE
    INITIALIZE_TAPE:
           GLOBAL   INIT_TAPE
    INIT_TAPE:
             LD     A,0                            ;CLEAR THE HP64000 AREA
             LD     [CA],A
             LD     [CSA],A                        ;AND THE TAPE CONTROL STATUS AREA
             DEC    A
             LD     [OVERLAY_NUMBER],A             ;MAKE THE OVERLAY NUMBER -1 (INVALID)
             NEXT_STATE 0                          ;SET THE IDLE STATE!
             RET

    TAPE_MANAGER:
    ;BEGIN        (Ordinarily registers are restored; retain only the pushes and pops you need.)

             LD     A,[CA]                         ;TEST THE STATUS OF THE FILE
             OR     A
             JP     M,END_OF_STATE_MACHINE         ;IF THERE IS A COMMAND IN THE BUFFER
             JR     Z,AB_REQ
             CP     1                              ;END OF FILE ON READ FROM HP64000
             JP     NZ,ERROR
    ;*
    ;*        AT THIS POINT ANY SIM I/O FUNCTIONS ARE COMPLETE; TEST FOR ABORTS (KILLS)
    ;*
             GLOBAL AB_REQ
    AB_REQ:  LD     A,[CSA]                         ;IF COMMAND IS TO KILL TAPE COMMAND
             CP     KILL_TAPE
             JR     NZ,CASE_STATE
             LD     A,[TAPE_STATE]                  ;CHECK THE STATE OF THE TAPE
    ;*
             CP     3                               ;CHECK STATE 0,1,2
             JP     C,STATE_PRE_IDLE                ;FILE NOT OPENED
    ;*
             CP     6                               ;STATE 3,4,5
             JP     C,STATE_CLOSE                   ;FILE OPENED TRY TO CLOSE IT
    ;*
    ;*               FALL THRU TO CASE STATEMENT     ;IF STATE = 6,7
    ;*                                               ;FILE IS TRYING TO CLOSE
    ;*
    ;*
    ;*        CASE   TAPE_STATE,(IDLE,RENAME,OPEN,READ1,READ2,MOVE2VRAM,CLOSE,PRE_IDLE)
    ;*
    CASE_STATE:
    ;*
    ;*
             LD     HL,[NEXT_STATE_ADDRESS]
             JP     [HL]
    STATE_VECTORS:
             DEFW   STATE_IDLE                      ;STATE 0
             DEFW   STATE_RENAME                    ;      1
             DEFW   STATE_OPEN                      ;      2
             DEFW   STATE_READ_1                    ;      3
             DEFW   STATE_READ_2                    ;      4
             DEFW   STATE_MOVE2RAM                  ;      5
             DEFW   STATE_CLOSE                     ;      6
             DEFW   STATE_PRE_IDLE                  ;      7
             DEFW   WRITE_1
    ;*
    ;*        IF THE MACHINE IS IDLE IT'S OK TO TEST FOR ANOTHER READ REQUEST
    ;*
    STATE_IDLE:                                     ;STATE 0
             LD     A,[CSA]                         ;TEST THE COMMAND STATUS AREA
             OR     A
             JP Z,END_OF_STATE_MACHINE
    ;*
             NEXT_STATE 1
    ;*
    ;*        ASSIGN THE SIM I/O FILE TO THE CURRENT OVERLAY NAME
    ;*
    STATE_RENAME:                                   ;STATE 1
             LD     A,[OVERLAY_NUMBER]
             LD     HL,SAMPLE_NAME
             LD     DE,RNAM_BUF                     ;POINT TO THE RENAME BUFFER IN THE COMMON ATTRIBUTES AREA
             LD     BC,SAMPLE_NAME_LEN              ;NO NAME COULD BE MORE THAN TEN BYTES LONG COULD IT?
             LDIR                                   ;MOVE THE OVERLAY DATA TO THE RENAME BUFFER
    ;*
    ;*
    ;*
             LD     BC,10*256+"0"                   ;GET THE OVERLAY NUMBER INTO ASCII
    OV_2_ASCII_1:
             OR     A
             SBC    A,B                             ;DIVIDE OVERLAY NUMBER BY 10
             INC    C                               ;SET THE NUMBER OF TENS IN C (DOESN'T RESET CARRY)
             JR     NC,OV_2_ASCII_1                 ;CARRY WAS SET BY SUBTRACT IF B>A
             DEC    C                               ;SAVE THE TENS BYTE
             ADD    A,B                             ;ADD TENS TO GET THE REMAINDER
             LD     B,"0"                           ;SAVE THE ONES BYTE
             ADD    A,B
             LD     B,A
             LD     A,C
             CP     "0"                             ;CONVERT TO ASCII
             JR     NZ,OV_2_ASCII_2
             LD     A,"_"                           ;SPECIAL CASE
    OV_2_ASCII_2:
             LD     [DE],A                          ;DE IS POINTING TO THE FILENAME FROM THE LDIR ABOVE
             INC    DE
             LD     A,B
             LD     [DE],A
    ;*
    ;*        ASSIGN THE FILE
    ;*
             LD     A,RENAME
             LD     [CA],A
    ;*
             NEXT_STATE 2                           ;NEXT OPEN
    ;*
    ;*
    STATE_OPEN:                                     ;STATE 2
    ;*
    ;*        OPEN THE FILE
    ;*
             LD     A,ABSOLUTE                      ;LOAD THE FILE TYPE
             LD     [FILETYPE],A
             LD     A,0                             ;DISK NUMBER
             LD     [DISC_NUM],A
             LD     A,OPEN                          ;OPEN THE CURRENT FILE
             LD     [CA],A
             LD     A,[CSA]                         ;NEXT STATE READ OR WRITE?
             NEXT_STATE 3                           ;NEXT STATE = READ_1
    STATE_READ_1:                                   ;STATE 3
    ;*
    ;*        READ THE FIRST RECORD TO SKIP OVER IT
    ;*
             LD     A,MAXBUFLN                      ;SET THE INPUT BUFFER LENGTH
             LD     [BUF_LEN],A                     ;
             LD     A,READ
             LD     [CA],A                          ;READ THE FIRST RECORD

             NEXT_STATE 4

    ;*
    ;*        READ REMAINING RECORDS AND MOVE TO RAM
    ;*
    STATE_READ_2:                                   ;STATE 4
             LD     A,MAXBUFLN                      ;SET THE INPUT BUFFER LENGTH
             LD     [BUF_LEN],A                     ;
             LD     A,READ                          ;
             LD     [CA],A

             NEXT_STATE 5                           ;NEXT STATE = READ A DATA RECORD

    ;*
    ;*        MOVE THE LAST BUFFER TO RAM
    ;*
    STATE_MOVE2RAM:                                 ;STATE 5
             LD     A,[CA]                          ;CHECK THE RETURN STATUS
             OR     A
             JR     Z,NO_EOF                        ;END OF FILE?
    ;*
    ;*

             NEXT_STATE 6                           ;NEXT STATE = CLOSE FILE
    NO_EOF:                                         ;MOVE THE CURRENT OVERLAY TO MEMORY
             LD     HL,[REC_LEN]                    ;GET THE NUMBER OF BYTES TO MOVE TO RAM
             LD     C,H
             LD     B,L
    ;*
             LD     HL,[LOADADDR]                   ;GET THE LOAD ADDRESS AND CHECK TO SEE IF IT IS IN VRAM
             LD     D,L
             LD     E,H
             LD     HL,BUFFER                       ;FROM ADDRESS

             LD     A,[CSA]
             CP     WRITE_TAPE
             JR     Z,WRITE_1

             LDIR
    ;*

             NEXT_STATE 4                           ;NEXT STATE = READ A DATA RECORD
    ;*
    ;*        CLOSE OVERLAY FILE
    ;*
    STATE_CLOSE:                                    ;STATE 6
             LD     A,CLOSE                         ;CLOSE THE FILES
             LD     [CA],A

             NEXT_STATE 7                           ;NEXT STATE = PRE-IDLE
    ;*
    ;*
    ;*        NEXT STATE IS IDLE
    ;*
    STATE_PRE_IDLE:                                 ;STATE 7
             LD     A,0                             ;NEXT STATE = PRE-IDLE
             LD     [CSA],A                         ;CLEAR THE COMMAND STATUS BUFFER
             DEC    A
             LD     [OVERLAY_NUMBER],A              ;SET THE OVERLAY NUMBER TO OUT OF RANGE
             NEXT_STATE 0
    ;*
    ;*        WRITE OUT 256 DATA BYTES TO AN OVERLAY! OH BOY!
    ;*
    WRITE_1:                                        ;GET HERE FROM MOVE2RAM1
             EX     DE,HL
             LDIR
             LD     A,WRITE
             LD     [CA],A
             NEXT_STATE 6
    ;*
    ;*
    ;*

    ;  END (TAPE_MANAGER)

    END_OF_STATE_MACHINE:
           XOR A
           RET
    ;***************************************************************************
    ;***************************************************************************
    ERROR:
    ;  BEGIN       (Ordinarily registers are restored; retain only the pushes and pops you need.)

           LD C,A
           LD A,[OVERLAY_NUMBER]                    ;SAVE THE OVERLAY NUMBER IN A
           LD B,A
           LD A,[TAPE_STATE]
           LD HL,0                                  ;B HAS THE FUNCTION CODE
           LD [HL],A                                ;C HAS THE ERROR CODE
    ;
    ;   LD [HL] HAS JUST CAUSED A BINK TO OCCUR ON THE HP64000
    ;   THIS IS TO LET THE USER KNOW THERE HAS BEEN AN ERROR
    ;
           XOR     A
           LD      [CA],A                           ;CLEAR THE ERROR FROM THE HP64000
           INC     A                                ;PRETEND THE ERROR WAS A CRC CHECK FROM ADAM'S TAPE
           LD      [CSA],A
           LD      HL,[STATE_VECTORS+0000]
           LD      [NEXT_STATE_ADDRESS],HL
           RET

    ;  END (TAPE_ERR)

    ;***************************************************************************
    ;***************************************************************************
    ;
    ;   OVERLAY NAMES
    ;
    ;         -------- -------- -------- -------- --------
    ;        :LENGTH  :FILENAME ------> : USER ID         :
    ;        :BYTE    :UP TO 9 BYTES    : UP TO 5 BYTES   :
    ;         -------- -------- -------- -------- --------
    ;        LENGTH_BYTE := (((((LENGTH OF FILE NAME)+1)/2)-1)*32) + ((LENGTH OF USER ID)/2)*8)
    ;        FILENAME MUST BE ODD NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
    ;        USER ID MUST BE EVEN NUMBER OF BYTES LONG MAY BE PADDED WITH ONE SPACE.
    ;
    ;*****************************************************************************************
    ;*****************************************************************************************
    ;*
    ;*  OVERLAY NAME 0
    ;*
    SAMPLE_NAME
    OVLAY0   DEFB   FL_NM_LN0*32+US_ID_LN0*8        ;LENGTH DESCRIPTION BYTE
    NAM_0    DEFB   "OVL_1"                         ;MUST BE ODD NUMBER OF LETTERS
    USID0    DEFB   ""                              ;MUST BE EVEN NUMBER OF LETTERS
    FL_NM_LN0 EQU   ((USID0-NAM_0+1)/2)-1           ;LENGTH OF FILENAME IN WORDS
    US_ID_LN0 EQU   ($-USID0)/2                     ;LENGTH OF USERID IN WORDS
    SAMPLE_NAME_LEN EQU $-SAMPLE_NAME-2             ;NUMBER OF BYTES TO MOVE = 4
    ;***********************************************************************
     DATA
     GLOBAL NEXT_STATE_ADDRESS
    NEXT_STATE_ADDRESS DEFS 2                       ;POINTER TO NEXT ENTRY STATE
    DEVICE_ID          DEFS 1                       ;DEVICE INDEPENDENCE SIMULATED